/*
 *  ati.h
 *  
 *  Created by Slice on 19.02.12.
 *  
 *  the code ported from Chameleon project as well as from RadeonFB by Joblo and RadeonHD by dong
 *  big thank to Islam M. Ahmed Zaid for the updating the collection
 */

#include "Platform.h"  //this include needed for Uefi types
#include "ati_reg.h"

#define OFFSET_TO_GET_ATOMBIOS_STRINGS_START 0x6e
#define DATVAL(x)			{kPtr, sizeof(x), (UINT8 *)x}
#define STRVAL(x)			{kStr, sizeof(x)-1, (UINT8 *)x}
#define BYTVAL(x)			{kCst, 1, (UINT8 *)(UINTN)x}
#define WRDVAL(x)			{kCst, 2, (UINT8 *)(UINTN)x}
#define DWRVAL(x)			{kCst, 4, (UINT8 *)(UINTN)x}
// QWRVAL would work only in 64 bit
//#define QWRVAL(x)			{kCst, 8, (UINT8 *)(UINTN)x}
#define NULVAL				{kNul, 0, (UINT8 *)NULL}


/*Typedefs ENUMS*/
typedef enum {
	kNul,
	kStr,
	kPtr,
	kCst
} type_t;

typedef enum {
	CHIP_FAMILY_UNKNOW,
	/* Old */
	CHIP_FAMILY_R420,
	CHIP_FAMILY_R423,
	CHIP_FAMILY_RV410,
	CHIP_FAMILY_RV515,
	CHIP_FAMILY_R520,
	CHIP_FAMILY_RV530,
	CHIP_FAMILY_RV560,
	CHIP_FAMILY_RV570,
	CHIP_FAMILY_R580,
	/* IGP */
	CHIP_FAMILY_RS600,
	CHIP_FAMILY_RS690,
	CHIP_FAMILY_RS740,
	CHIP_FAMILY_RS780,
	CHIP_FAMILY_RS880,
	/* R600 */
	CHIP_FAMILY_R600,
	CHIP_FAMILY_RV610,
	CHIP_FAMILY_RV620,
	CHIP_FAMILY_RV630,
	CHIP_FAMILY_RV635,
	CHIP_FAMILY_RV670,
	/* R700 */
	CHIP_FAMILY_RV710,
	CHIP_FAMILY_RV730,
	CHIP_FAMILY_RV740,
	CHIP_FAMILY_RV770,
	CHIP_FAMILY_RV772,
	CHIP_FAMILY_RV790,
	/* Evergreen */
	CHIP_FAMILY_CEDAR,
	CHIP_FAMILY_CYPRESS,
	CHIP_FAMILY_HEMLOCK,
	CHIP_FAMILY_JUNIPER,
	CHIP_FAMILY_REDWOOD,
	/* Northern Islands */
	CHIP_FAMILY_BARTS,
	CHIP_FAMILY_CAICOS,
	CHIP_FAMILY_CAYMAN,
	CHIP_FAMILY_TURKS,
	/* Southern Islands */
	CHIP_FAMILY_PALM,
	CHIP_FAMILY_SUMO,
    CHIP_FAMILY_SUMO2,
	CHIP_FAMILY_ARUBA,
	CHIP_FAMILY_TAHITI,
	CHIP_FAMILY_PITCAIRN,
	CHIP_FAMILY_VERDE,
	CHIP_FAMILY_OLAND,
	CHIP_FAMILY_HAINAN,
	CHIP_FAMILY_BONAIRE,
	CHIP_FAMILY_KAVERI,
	CHIP_FAMILY_KABINI,
	CHIP_FAMILY_HAWAII,
	/* ... */
	CHIP_FAMILY_MULLINS,
    CHIP_FAMILY_TOPAS,
    CHIP_FAMILY_AMETHYST,
    CHIP_FAMILY_TONGA,
	CHIP_FAMILY_LAST
} ati_chip_family_t;

typedef struct {
	const CHAR8		*name;
	UINT8			ports;
} card_config_t;

typedef enum {
	kNull,
	/* OLDController */
	kWormy,
	kAlopias,
	kCaretta,
	kKakapo,
	kKipunji,
	kPeregrine,
	kRaven,
	kSphyrna,
	/* AMD2400Controller */
	kIago,
	/* AMD2600Controller */
	kHypoprion,
	kLamna,
	/* AMD3800Controller */
	kMegalodon,
	kTriakis,
	/* AMD4600Controller */
	kFlicker,
	kGliff,
	kShrike,
	/* AMD4800Controller */
	kCardinal,
	kMotmot,
	kQuail,
	/* AMD5000Controller */
	kDouc,
	kLangur,
	kUakari,
	kZonalis,
	kAlouatta,
	kHoolock,
	kVervet,
	kBaboon,
	kEulemur,
	kGalago,
	kColobus,
	kMangabey,
	kNomascus,
	kOrangutan,
	/* AMD6000Controller */
	kPithecia,
	kBulrushes,
	kCattail,
	kHydrilla,
	kDuckweed,
	kFanwort,
	kElodea,
	kKudzu,
	kGibba,
	kLotus,
	kIpomoea,
	kMuskgrass,
	kJuncus,
	kOsmunda,
	kPondweed,
	kSpikerush,
	kTypha,
	/* AMD7000Controller */
	kNamako,
	kAji,
	kBuri,
	kChutoro,
	kDashimaki,
	kEbi,
	kGari,
	kFutomaki,
	kHamachi,
	kOPM,
	kIkura,
	kIkuraS,
	kJunsai,
	kKani,
	kKaniS,
	kDashimakiS,
	kMaguro,
	kMaguroS,
	/* AMD8000Controller */
  kBaladi,
	/* AMD9000Controller */
  kExmoor,
  kBasset,
	kGreyhound,
  kLabrador,
	kCfgEnd
} config_name_t;

typedef struct {
	UINT16			device_id;
	UINT32			subsys_id;
	ati_chip_family_t	chip_family;
	const CHAR8		*model_name;
	config_name_t		cfg_name;
} radeon_card_info_t;

typedef struct {
	DevPropDevice		*device;
	radeon_card_info_t	*info;
	pci_dt_t		*pci_dev;
	UINT8			*fb;
	UINT8			*mmio;
	UINT8                 *io;
	UINT8                 *rom;
	UINT32                rom_size;
	UINT64                vram_size;
	const CHAR8           *cfg_name;
	UINT8                 ports;
	UINT32                flags;
	BOOLEAN               posted;
} card_t;

// Chip flags
/* enum radeon_chip_flags {
	RADEON_FAMILY_MASK = 0x0000ffffUL,
	RADEON_FLAGS_MASK = 0xffff0000UL,
	RADEON_IS_MOBILITY = 0x00010000UL,
	RADEON_IS_IGP = 0x00020000UL,
	RADEON_SINGLE_CRTC = 0x00040000UL,
	RADEON_IS_AGP = 0x00080000UL,
	RADEON_HAS_HIERZ = 0x00100000UL,
	RADEON_IS_PCIE = 0x00200000UL,
	RADEON_NEW_MEMMAP = 0x00400000UL,
	RADEON_IS_PCI = 0x00800000UL,
	RADEON_IS_IGPGART = 0x01000000UL,
};*/
#define MKFLAG(n)   (1 << n)
#define FLAGTRUE    MKFLAG(0)
#define EVERGREEN   MKFLAG(1)
#define FLAGMOBILE	MKFLAG(2)
#define FLAGOLD     MKFLAG(3)
#define FLAGNOTFAKE MKFLAG(4)

typedef struct {
	type_t		type;
	UINT32		size;
	UINT8		*data;
} value_t;

typedef struct {
	UINT32		flags;
	BOOLEAN		all_ports;
	CHAR8		*name;
	BOOLEAN		(*get_value)(value_t *val, INTN index);
	value_t		default_val;
} AtiDevProp;

BOOLEAN get_bootdisplay_val(value_t *val, INTN index);
BOOLEAN get_vrammemory_val(value_t *val, INTN index);
BOOLEAN get_edid_val(value_t *val, INTN index);
BOOLEAN get_display_type(value_t *val, INTN index);
BOOLEAN get_name_val(value_t *val, INTN index);
BOOLEAN get_nameparent_val(value_t *val, INTN index);
BOOLEAN get_model_val(value_t *val, INTN index);
BOOLEAN get_conntype_val(value_t *val, INTN index);
BOOLEAN get_vrammemsize_val(value_t *val, INTN index);
BOOLEAN get_binimage_val(value_t *val, INTN index);
BOOLEAN get_binimage_owr(value_t *val, INTN index);
BOOLEAN get_romrevision_val(value_t *val, INTN index);
BOOLEAN get_deviceid_val(value_t *val, INTN index);
BOOLEAN get_mclk_val(value_t *val, INTN index);
BOOLEAN get_sclk_val(value_t *val, INTN index);
BOOLEAN get_refclk_val(value_t *val, INTN index);
BOOLEAN get_platforminfo_val(value_t *val, INTN index);
BOOLEAN get_vramtotalsize_val(value_t *val, INTN index);
BOOLEAN get_dual_link_val(value_t *val, INTN index);
BOOLEAN get_name_pci_val(value_t *val, INTN index);

extern card_config_t card_configs[];
extern radeon_card_info_t radeon_cards[];
extern AtiDevProp ati_devprop_list[];
extern const CHAR8 *chip_family_name[];
